package hyh.com.udpclientdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class MainActivity extends AppCompatActivity {

    int id=2;
    int toId =1;
    String content="niyehao";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        net();
    }
    DatagramSocket datagramSocket;
    byte buf[] = new byte[1024];
    InetAddress inetAddress;

    public void net() {
        try {
            inetAddress = InetAddress.getByName("119.29.16.173");
//			inetAddress = InetAddress.getByName("127.0.0.1");
        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    datagramSocket = new DatagramSocket();

                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            while (true) {
                                try {
                                    ClientInfo clientInfo = new ClientInfo();
                                    clientInfo.id = id;
                                    clientInfo.msgType = ClientInfo.MsgType.HeartBeat;
                                    Gson gson = new Gson();
                                    String json = gson.toJson(clientInfo);
                                    DatagramPacket datagramPacket = new DatagramPacket(json.getBytes(),json.getBytes().length,inetAddress, 8888);
                                    datagramSocket.send(datagramPacket);
                                    Thread.sleep(5000);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                    }).start();

                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            recv();
                        }
                    }).start();

                    conn();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void conn() {

        try {
            Thread.sleep(1000);
            ClientInfo clientInfo = new ClientInfo();
            clientInfo.id = id;
            clientInfo.toId = toId;
            clientInfo.msgType = ClientInfo.MsgType.UDPConn;
            Gson gson = new Gson();
            String json = gson.toJson(clientInfo);
            DatagramPacket datagramPacket = new DatagramPacket(json.getBytes(),json.getBytes().length, inetAddress, 8888);
            datagramSocket.send(datagramPacket);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    String toIp;
    int toPort;

    public void recv() {
        while (true) {
            try {
                byte buf[] = new byte[128];
                DatagramPacket packet = new DatagramPacket(buf, buf.length);
                datagramSocket.receive(packet);
                Gson gson = new Gson();
                String json = new String(packet.getData(), 0,
                        packet.getLength());
                final ClientInfo clientInfo = gson.fromJson(json, ClientInfo.class);
                switch (clientInfo.msgType) {
                    case ClientInfo.MsgType.UDPFail:
                        System.out.println("UDPFail"+System.currentTimeMillis());
                        conn();
                        break;
                    case ClientInfo.MsgType.UDPSuccess:
                        toIp = clientInfo.ip;
                        toPort = clientInfo.port;
                        System.out.println("UDPSuccess"+System.currentTimeMillis());
                        new Thread(new Runnable(){

                            @Override
                            public void run() {
                                try {
                                    Thread.sleep(2000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                while(true){
//								System.out.println("发送你也好");
//                                    MainActivity.this.runOnUiThread(new Runnable() {
//                                        @Override
//                                        public void run() {
//                                            Toast.makeText(MainActivity.this,toIp+":"+toPort+"你好",Toast.LENGTH_SHORT).show();
//                                        }
//                                    });
                                    send(toIp,toPort,content);
                                    try {
                                        Thread.sleep(2000);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }

                        }).start();
                        break;
                    case ClientInfo.MsgType.UDPConn:
                        System.out.println("UDPConn"+System.currentTimeMillis());
                        connReply(clientInfo);
                        break;
                    case ClientInfo.MsgType.MsgSend:
                        MainActivity.this.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this,clientInfo.body.toString(),Toast.LENGTH_SHORT).show();
                            }
                        });
                        System.out.println("接收"+clientInfo.body);
                        break;
                }
            } catch (JsonSyntaxException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public  void send(String toIp,int toPort,String str){
        try {
            ClientInfo clientInfo = new ClientInfo();
            clientInfo.id = id;
            clientInfo.toId = toId;
            clientInfo.body = str;
            clientInfo.msgType = ClientInfo.MsgType.MsgSend;
            InetAddress addr = InetAddress.getByName(toIp);
            int port = toPort;
            Gson gson = new Gson();
            String json = gson.toJson(clientInfo);
            DatagramPacket datagramPacket = new DatagramPacket(json.getBytes(),json.getBytes().length, addr, port);
            datagramSocket.send(datagramPacket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void connReply(ClientInfo clientInfo) {

        try {


            ClientInfo clientInfoServer = new ClientInfo();
            clientInfoServer.msgType = ClientInfo.MsgType.UDPSuccess;
            clientInfoServer.id = id;
            clientInfoServer.toId = clientInfo.id;
            Gson gsonServer = new Gson();
            String jsonServer = gsonServer.toJson(clientInfoServer);
            DatagramPacket datagramPacketServer = new DatagramPacket(
                    jsonServer.getBytes(), jsonServer.getBytes().length,
                    inetAddress, 8888);
            datagramSocket.send(datagramPacketServer);

            InetAddress inetAddressClient = InetAddress
                    .getByName(clientInfo.ip);
            int port = clientInfo.port;

            {

                Log.e("androidLog","打洞"+clientInfo.ip+":"+clientInfo.port);
                ClientInfo clientInfoClient = new ClientInfo();
                clientInfoClient.msgType = ClientInfo.MsgType.EmptyPacket;
                Gson gsonClient = new Gson();
                String jsonClient = gsonClient.toJson(clientInfoClient);
                DatagramPacket datagramPacketClient = new DatagramPacket(
                        jsonClient.getBytes(), jsonClient.getBytes().length,
                        inetAddressClient, port);
                datagramSocket.send(datagramPacketClient);
            }

            {
                Log.e("androidLog","打洞"+clientInfo.ip+":"+clientInfo.port);
                ClientInfo clientInfoClient = new ClientInfo();
                clientInfoClient.msgType = ClientInfo.MsgType.EmptyPacket;
                Gson gsonClient = new Gson();
                String jsonClient = gsonClient.toJson(clientInfoClient);
                DatagramPacket datagramPacketClient = new DatagramPacket(
                        jsonClient.getBytes(), jsonClient.getBytes().length,
                        inetAddressClient, port);
                datagramSocket.send(datagramPacketClient);
            }

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
